from django.shortcuts import render
from web.form.issues import IssuesModelForm, IssuesReplyModelForm, InviteModelForm
from django.http import JsonResponse
from web import models
from utils.pagination import Pagination
from django.views.decorators.csrf import csrf_exempt
import json
from django.utils.safestring import mark_safe
from utils.encrypt import uid
from django.urls import reverse
import datetime


class CheckFilter(object):
    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = data_list
        self.request = request

    def __iter__(self):
        for item in self.data_list:
            key = str(item[0])
            text = item[1]
            ck = ""
            # 如果当前用户请求的URL中status和当前循环key相等

            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                ck = "checked"
                value_list.remove(key)
            else:
                value_list.append(key)

            # 为自己生成一个url
            # 在当前基础上增加一项
            # status=1&age=19
            query_dict = self.request.GET.copy()
            query_dict._mutable = True  # 默认是不会被修改的，把这个改为true才可以
            query_dict.setlist(self.name, value_list)  # 相当于把status=11&status=22&status=33&age=19

            if 'page' in query_dict:
                query_dict.pop('page')
            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info,
                                     param_url)  # urlencode这个方法可以把{‘status’：[1,2,3]}变成status=1&status=2&status=3
            else:
                url = self.request.path_info

            tpl = '<a class="cell" href="{url}"><input type="checkbox" {ck} /><label>{k1}</label></a>'
            html = tpl.format(url=url, ck=ck, k1=text)
            yield mark_safe(html)
        # yield mark_safe("<a><input type='checkbox' />处理中</a>")


class SelectFilter(object):
    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = data_list
        self.request = request

    def __iter__(self):
        yield mark_safe("<select class='select2' multiple='multiple' style='width:100%;' >")
        for item in self.data_list:
            key = str(item[0])
            text = item[1]

            selected = ""
            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                selected = 'selected'
                ck = "checked"
                value_list.remove(key)
            else:
                value_list.append(key)

            query_dict = self.request.GET.copy()
            query_dict._mutable = True  # 默认是不会被修改的，把这个改为true才可以
            query_dict.setlist(self.name, value_list)  # 相当于把status=11&status=22&status=33&age=19
            if 'page' in query_dict:
                query_dict.pop('page')
            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info,
                                     param_url)  # urlencode这个方法可以把{‘status’：[1,2,3]}变成status=1&status=2&status=3
            else:
                url = self.request.path_info
            html = "<option value='{url}' {selected}>{text}</option>".format(url=url, selected=selected, text=text)
            yield mark_safe(html)
        yield mark_safe("</select>")


def issues(request, project_id):
    if request.method == "GET":
        # 根据url进行筛选就可以了
        allow_filter_name = ['issues_type', 'status', 'priority', 'assign', 'attention']

        # 筛选条件（通过get传过来的参数来实现）
        # ？status=1&issues_type=1
        condition = {}
        for name in allow_filter_name:
            value_list = request.GET.getlist(name)  # [1,2]  get获取一个值  getlist获取所有值
            if not value_list:
                continue
            condition["{}__in".format(name)] = value_list
            """condition = {
                 "status__in":[1,2],
                 "issues_type_in":[1,]
            }"""

        # 分页获取数据
        #     print(condition)
        queryset = models.Issues.objects.filter(project_id=project_id).filter(**condition)

        page_object = Pagination(current_page=request.GET.get('page'),
                                 all_count=queryset.count(),
                                 base_url=request.path_info,
                                 query_params=request.GET,
                                 per_page=10)

        issues_object_list = queryset[page_object.start:page_object.end]

        form = IssuesModelForm(request)
        project_issues_type = models.IssuesType.objects.filter(project_id=project_id).values_list('id', 'title')

        project_total_user = [(request.tracer.project.creator_id, request.tracer.project.creator.username)]
        join_user = models.ProjectUser.objects.filter(project_id=project_id).values_list('user_id', 'user__username')
        project_total_user.extend(join_user)
        invite_form = InviteModelForm()
        return render(request, 'web/issues.html', {'invite_form': invite_form,
                                                   'form': form,
                                                   'issues_object_list': issues_object_list,
                                                   'page_html': page_object.page_html(),
                                                   "status_filter": CheckFilter('status', models.Issues.status_choices,
                                                                                request),
                                                   "priority_filter": CheckFilter('priority',
                                                                                  models.Issues.priority_choices,
                                                                                  request),
                                                   "issues_type_filter": CheckFilter('issues_type', project_issues_type,
                                                                                     request),
                                                   "assign_filter": SelectFilter('assign', project_total_user,
                                                                                 request),
                                                   "attention_filter": SelectFilter('attention', project_total_user,
                                                                                    request),
                                                   })

    # print(request.POST)
    form = IssuesModelForm(request, data=request.POST)
    if form.is_valid():
        # 添加问题
        form.instance.project = request.tracer.project
        form.instance.creator = request.tracer.user
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


def issues_detail(request, project_id, issues_id):
    issues_object = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()
    form = IssuesModelForm(request, instance=issues_object)
    return render(request, 'web/issues_detail.html', {'form': form, "issues_object": issues_object})


@csrf_exempt
def issues_record(request, project_id, issues_id):
    """初始化操作记录"""
    if request.method == 'GET':
        reply_list = models.IssuesReply.objects.filter(issues_id=issues_id, issues__project=request.tracer.project)
        # 将queryset转换为json格式
        date_list = []
        for row in reply_list:
            data = {'id': row.id,
                    'reply_type_text': row.get_reply_type_display(),
                    'content': row.content,
                    'creator': row.creator.username,
                    'datetime': row.create_datetime.strftime("%Y-%m-%d %H:%M"),
                    'parent_id': row.reply_id,
                    }
            date_list.append(data)
        return JsonResponse({'status': True, 'data': date_list})
    form = IssuesReplyModelForm(data=request.POST)
    if form.is_valid():
        form.instance.issues_id = issues_id
        form.instance.reply_type = 2
        form.instance.creator = request.tracer.user

        instance = form.save()
        info = {
            'id': instance.id,
            'reply_type_text': instance.get_reply_type_display(),
            'content': instance.content,
            'creator': instance.creator.username,
            'datetime': instance.create_datetime.strftime("%Y-%m-%d %H:%M"),
            'parent_id': instance.reply_id,
        }
        return JsonResponse({'status': True, 'data': info})
    return JsonResponse({'status': False, 'error': form.errors})


@csrf_exempt
def issues_change(request, project_id, issues_id):
    issues_object = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()
    post_dict = json.loads(request.body.decode('utf-8'))
    print(post_dict)
    name = post_dict.get('name')
    value = post_dict.get('value')
    field_object = models.Issues._meta.get_field(name)
    # 1,数据库字段更新
    # 1.1 文本
    if name in ["subject", "desc", "start_date", "end_date"]:
        if not value:
            if not field_object.null:
                return JsonResponse({'status': False, 'error': "你选择的值不能为空"})
            setattr(issues_object, name, None)
            issues_object.save()
            # 生成记录
            change_record = "{}更新为空".format(field_object.verbose_name)
        else:
            setattr(issues_object, name, value)
            issues_object.save()
            # 生成记录 更新value  filed_object.verbose_name
            change_record = "{}更新为{}".format(field_object.verbose_name, value)
        new_object = models.IssuesReply.objects.create(reply_type=1,
                                                       issues=issues_object,
                                                       content=change_record,
                                                       creator=request.tracer.user)
        new_reply_dict = {'id': new_object.id,
                          'reply_type_text': new_object.get_reply_type_display(),
                          'content': new_object.content,
                          'creator': new_object.creator.username,
                          'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
                          'parent_id': new_object.reply_id,
                          }
        return JsonResponse({'status': True, 'data': new_reply_dict})
    # 1.2 FK字段
    if name in ['issues_type', 'module', 'parent', 'assign']:
        if not value:
            if not field_object.null:  # 不允许为空
                return JsonResponse({'status': False, 'error': "你选择的值不能为空"})
            setattr(issues_object, name, None)
            issues_object.save()
            # 生成记录
            change_record = "{}更新为空".format(field_object.verbose_name)
        else:
            if name == 'assign':
                # 是否是项目的创建者
                if value == str(request.tracer.project.creator_id):
                    instance = request.tracer.project.creator
                else:
                    project_user_object = models.ProjectUser.objects.filter(project_id=project_id,
                                                                            user_id=value).first()
                    if project_user_object:
                        instance = project_user_object
                    else:
                        instance = None
                # 是否是项目的参与者
                if not instance:
                    return JsonResponse({'status': False, 'error': "你选择的值不存在"})
                setattr(issues_object, name, instance)
                issues_object.save()
                change_record = "{}更新为{}".format(field_object.verbose_name, str(instance))  # value根据文本，获取内容

            else:
                # 条件判断：用户输入的值，是自己的值
                instance = field_object.remote_field.model.objects.filter(id=value, project_id=project_id).first()
                if not instance:
                    return JsonResponse({'status': False, 'error': "你选择的值不存在"})

                setattr(issues_object, name, instance)
                issues_object.save()
                change_record = "{}更新为{}".format(field_object.verbose_name, str(instance))  # value根据文本，获取内容

        new_object = models.IssuesReply.objects.create(reply_type=1,
                                                       issues=issues_object,
                                                       content=change_record,
                                                       creator=request.tracer.user)
        new_reply_dict = {'id': new_object.id,
                          'reply_type_text': new_object.get_reply_type_display(),
                          'content': new_object.content,
                          'creator': new_object.creator.username,
                          'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
                          'parent_id': new_object.reply_id,
                          }
        return JsonResponse({'status': True, 'data': new_reply_dict})
    # 1.3 choices字段
    if name in ['priority', 'status', 'mode']:
        selected_text = None
        for key, text in field_object.choices:
            if str(key) == value:
                selected_text = text
        if not selected_text:
            return JsonResponse({'status': False, 'error': "你选择的值不能为空"})
        setattr(issues_object, name, value)
        issues_object.save()
        change_record = "{}更新为{}".format(field_object.verbose_name, selected_text)
        new_object = models.IssuesReply.objects.create(reply_type=1,
                                                       issues=issues_object,
                                                       content=change_record,
                                                       creator=request.tracer.user)
        new_reply_dict = {'id': new_object.id,
                          'reply_type_text': new_object.get_reply_type_display(),
                          'content': new_object.content,
                          'creator': new_object.creator.username,
                          'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
                          'parent_id': new_object.reply_id,
                          }
        return JsonResponse({'status': True, 'data': new_reply_dict})
    # 1.4 M2M字段
    if name == "attention":
        if not isinstance(value, list):
            return JsonResponse({'status': False, 'error': "数据格式错误"})
        if not value:
            issues_object.attention.set([])  # []也可以改为value
            issues_object.save()
            change_record = "{}更新为空".format(field_object.verbose_name)

        else:
            # values[1,2,3,4]  判断id是否为项目成员
            # 获取当前项目的所有成员
            user_dict = {str(request.tracer.project.creator_id): request.tracer.project.creator.username}
            project_user_list = models.ProjectUser.objects.filter(project_id=project_id)
            for item in project_user_list:
                user_dict[str(item.user_id)] = item.user.username
            username_list = []
            for user_id in value:
                username = user_dict.get(str(user_id))
                if not username:
                    return JsonResponse({'status': False, 'error': "数据错误"})
                username_list.append(username)
            issues_object.attention.set(value)  # []也可以改为value
            issues_object.save()
            change_record = "{}更新为空{}".format(field_object.verbose_name, ",".join(username_list))
        new_object = models.IssuesReply.objects.create(reply_type=1,
                                                       issues=issues_object,
                                                       content=change_record,
                                                       creator=request.tracer.user)
        new_reply_dict = {'id': new_object.id,
                          'reply_type_text': new_object.get_reply_type_display(),
                          'content': new_object.content,
                          'creator': new_object.creator.username,
                          'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
                          'parent_id': new_object.reply_id,
                          }
        return JsonResponse({'status': True, 'data': new_reply_dict})
    # 2，生成操作记录
    return JsonResponse({'status': False, 'error': '滚'})


def invite_url(request, project_id):
    """生成邀请码"""
    form = InviteModelForm(data=request.POST)
    if form.is_valid():
        """
        1.创建一个随机验邀请码
        2，把验证码保存到数据库
        3，只有创建者才能邀请 限制
        """
        if request.tracer.user != request.tracer.project.creator:
            form.add_error('period', "没有权限创建邀请码")
            return JsonResponse({'status': False, 'error': form.errors})
        random_invite_code = uid(request.tracer.user.phone)
        form.instance.project = request.tracer.project
        form.instance.code = random_invite_code
        form.instance.creator = request.tracer.user
        form.save()
        # 将邀请码返回给前端，前端页面上展示出来。

        url_path = reverse('invite_join', kwargs={'code': random_invite_code})
        url = "{scheme}://{host}{path}".format(scheme=request.scheme,
                                               host=request.get_host(),
                                               path=url_path)

        return JsonResponse({'status': True, 'data': url})
    return JsonResponse({'status': False, 'error': form.errors})


def invite_join(request, code):
    """访问邀请码"""
    invite_object = models.ProjectInvite.objects.filter(code=code).first()

    if not invite_object:
        return render(request, 'web/invite_join.html', {'error': "邀请码不存在"})
    if invite_object.project.creator == request.tracer.user:
        return render(request, 'web/invite_join.html', {'error': "创建者无需再加入项目"})
    exists = models.ProjectUser.objects.filter(project=invite_object.project, user=request.tracer.user).exists()
    if exists:
        return render(request, 'web/invite_join.html', {'error': "已经加入项目，无需再加入"})
    # 最多应许的成员 要进入项目创建者的限制)
    max_member = request.tracer.price_policy.project_member

    # 目前的所有成员(包含创建者和参与者)
    current_member = models.ProjectUser.objects.filter(project=invite_object.project).count()
    current_member = current_member + 1
    if current_member >= max_member:
        return render(request, 'web/invite_join.html', {'error': "项目成员超限制，请升级套餐"})

    # 邀请码是否过期？
    current_datetime = datetime.datetime.now()
    limit_datetime = invite_object.create_datetime + datetime.timedelta(minutes=invite_object.period)
    if current_datetime > limit_datetime:
        return render(request, 'web/invite_join.html', {'error': "邀请码已经过期"})

    # 数量限制
    if invite_object.count:
        # 有数量限制
        if invite_object.use_count >= invite_object.count:
            return render(request, 'invite_join.html', {'error': "邀请码数已经使用完"})
        invite_object.use_count += 1
        invite_object.save()

    # 无数量限制
    models.ProjectUser.objects.create(user=request.tracer.user, project=invite_object.project)
    return render(request, 'invite_join.html', {'project': invite_object.project})
